package com.fyt.reachgo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fyt.reachgo.domain.Result;
import com.fyt.reachgo.domain.User;
import com.fyt.reachgo.domain.VO.LoginVO;
import com.fyt.reachgo.domain.dto.LoginDTO;
import com.fyt.reachgo.domain.dto.UserDTO;
import com.fyt.reachgo.service.UserService;
import com.fyt.reachgo.mapper.UserMapper;
import com.fyt.reachgo.utils.PasswordEncoder;
import com.fyt.reachgo.utils.RegexUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import static com.fyt.reachgo.utils.RedisConstants.*;
import static com.fyt.reachgo.utils.SystemConstants.USER_NICK_NAME_PREFIX;

/**
* @author 27675
* @description 针对表【user(用户信息表)】的数据库操作Service实现
* @createDate 2025-02-12 15:12:17
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    private final StringRedisTemplate stringRedisTemplate;
    @Autowired
    private UserMapper userMapper;

    public UserServiceImpl(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 实现发送验证码
     * @param mobile
     * @return
     */
    @Override
    public Result sendCode(String mobile) {

        // 生成6位随机数字
        String code = RandomUtil.randomNumbers(6);
        log.debug("验证码：" +  code);
        // 保存验证码到redis
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + mobile, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);
        // 成功并返回验证码
        return Result.success(code);
    }

    /**
     * 实现密码登录
     * @param loginDTO
     * @return
     */
    @Override
    public Result loginByPassword(LoginDTO loginDTO) {
        String mobile = loginDTO.getMobile();
        // 手机和格式是否正确？
        if (RegexUtils.isPhoneInvalid(mobile)) {
            return Result.error("手机号格式错误！");
        }
        String password = loginDTO.getPassword();
        // 根据手机号获取用户信息
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("mobile", mobile));
        // 密码错误
        if (!PasswordEncoder.matches(user.getPassword(), password)) {
            return Result.error("密码错误！");
        }
        // 密码正确，生成token
        String token = UUID.randomUUID().toString(true);
        String tokenKey = LOGIN_USER_KEY + token;
        log.debug("token：" + token);
        // 将查询到的数据转化为DTO
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        // 将数据插入redis
        stringRedisTemplate.opsForHash().putAll(tokenKey, BeanUtil.beanToMap(userDTO,new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true)
                        .setFieldValueEditor((s, o) -> o.toString())));
        // 设置生效时间
        stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);
        // 登录成功，修改登录时间
        user.setLastLogin(LocalDateTime.now());
        userMapper.updateById(user);

        return Result.success(buildLoginVO(user, token));
    }

    /**
     * 实现手机登录
     * @param loginDTO
     * @return
     */
    @Override
    public Result loginByMobile(LoginDTO loginDTO) {

        String mobile = loginDTO.getMobile();
        String code = loginDTO.getCode();
        // 如果验证码错误
        if (!code.equals(stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + mobile))) {
            return Result.error("验证码错误！");
        }
        // 验证码正确,根据手机号获取用户信息
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("mobile", mobile));
        if (user == null){
            // 用户不存在,创建一个用户
            user = createUser(mobile);
        }
        if (user.getStatus() == 0){
            return Result.error("账号已被封禁");
        }

        // 生成token
        String token = UUID.randomUUID().toString(true);
        String tokenKey = LOGIN_USER_KEY + token;
        log.debug("token：" + token);
        // 将查询到的数据转化为DTO
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        // 将数据插入redis
        stringRedisTemplate.opsForHash().putAll(tokenKey, BeanUtil.beanToMap(userDTO,new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true)
                        .setFieldValueEditor((s, o) -> o.toString())));
        // 设置生效时间
        stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);
        // 登录成功，修改登录时间
        user.setLastLogin(LocalDateTime.now());
        userMapper.updateById(user);
        // 构建返回结果
        return Result.success(buildLoginVO(user, token));
    }

    /**
     * 注册新用户
     * @param mobile
     * @return
     */
    private User createUser(String mobile) {
        User user = new User();
        user.setMobile(mobile);// 设置手机号
        user.setPassword(PasswordEncoder.encode("123456"));// 设置默认密码
        user.setNickname(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));// 雪花算法生成唯一用户名
        user.setUsername(user.getNickname());
        user.setStatus(1);// 账号首次注册默认为正常
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.insert(user);
        return user;
    }

    private LoginVO buildLoginVO(User user, String token) {
        LoginVO loginVO = new LoginVO();
        loginVO.setToken(token);// 设置token
        loginVO.setAvatar(user.getProfilePicture());// 设置头像
        loginVO.setNickname(user.getNickname());// 设置昵称
        loginVO.setMobile(user.getMobile());// 设置手机号

        return loginVO;
    }

}




